package com.clementheliou.cheliou.web.core.i18n;

import static javax.faces.context.FacesContext.getCurrentInstance;
import static org.springframework.web.jsf.FacesContextUtils.getRequiredWebApplicationContext;

import java.util.Enumeration;
import java.util.ResourceBundle;

import org.springframework.context.MessageSource;

import com.clementheliou.cheliou.business.technical.i18n.I18nTechnicalService;
import com.clementheliou.cheliou.web.controller.user.UserBean;

/**
 * <p>
 * This class exposes the Spring {@link MessageSource} to the application views
 * through the {@link I18nTechnicalService} interface. The
 * {@link ResourceBundle} is declared in the JSF configuration file with the
 * <tt>msg</tt> variable name. From JSF2 pages, with the JSTL syntax, we can
 * easily use it.
 * </p>
 * <p>
 * <u>Example:</u> <code>#{msg.property_key}</code>
 * </p>
 * 
 * @author Clément HELIOU (clement.heliou@gmail.com)
 * @see {@link I18nTechnicalService};
 * @see {@link ResourceBundle}.
 * @since 1.0
 */
public class MessageBundle extends ResourceBundle {

	/**
	 * Translation service.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	private I18nTechnicalService i18nService;

	/**
	 * Utilities about the user details.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	private UserBean userBean;

	/**
	 * <i> {@inheritDoc} </i>
	 * <p>
	 * If the key value is not found, the given key is returned.
	 * </p>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	protected Object handleGetObject(String key) {
		return getIi18nService().getAsResourceBundle(getUserBean().getCurrentLocale()).getString(key);
	}

	/**
	 * <i>{@inheritDoc}</i>
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @since 1.0
	 */
	@Override
	public Enumeration<String> getKeys() {
		return getIi18nService().getAsResourceBundle(getUserBean().getCurrentLocale()).getKeys();
	}

	/**
	 * Getter for the {@link #i18nService} field value if this one is null.
	 * Please not that the value is retrieved from the Spring context.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @return the {@link #i18nService} field value
	 * @since 1.0
	 */
	private I18nTechnicalService getIi18nService() {
		if (null == i18nService) {
			i18nService = getRequiredWebApplicationContext(getCurrentInstance()).getBean(I18nTechnicalService.class);
		}
		return i18nService;
	}

	/**
	 * Getter for the {@link #userBean} field value if this one is null. Please
	 * not that the value is retrieved from the Spring context.
	 * 
	 * @author Clément HELIOU (clement.heliou@gmail.com)
	 * @return the {@link #userBean} field value.
	 * @since 1.0
	 */
	private UserBean getUserBean() {
		if (null == userBean) {
			userBean = getRequiredWebApplicationContext(getCurrentInstance()).getBean(UserBean.class);
		}
		return userBean;
	}

}
